package com.pug.controller.user;

import com.pug.UserServerApplication;
import com.pug.annotation.SaveLog;
import com.pug.bo.KssUserBo;
import com.pug.controller.BaseController;
import com.pug.dto.MessageDto;
import com.pug.dto.UserDto;
import com.pug.pojo.KssUser;
import com.pug.result.ResultEnum;
import com.pug.result.ex.KsdBusinessException;
import com.pug.result.ex.KsdValidationException;
import com.pug.service.idwork.IdWorkService;
import com.pug.service.message.MessageMqSendUser;
import com.pug.service.message.MessageServiceMq;
import com.pug.service.user.UserServiceImpl;
import com.pug.threadlocal.UserThreadLocal;
import com.pug.utils.fn.asserts.Vsserts;
import com.pug.utils.pwd.DesUtils;
import com.pug.vo.KssUserVo;
import com.pug.vo.LoginByPwdVo;
import com.pug.vo.LogoutVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.UUID;

import static com.pug.constant.PugContants.*;

/**
 * Author: lqm
 * create: 2022/4/26 8:43
 * Lover: lqx
 *
 * @see
 */
@Slf4j
@RestController
@RefreshScope //及时刷新nacos配置文件
public class UserController extends BaseController {
    @Resource
    UserServiceImpl userService;
    @Resource
    IdWorkService idWorkService;
    @Resource
    MessageServiceMq messageServiceMq;
    @Resource
    StringRedisTemplate stringStringRedisTemplate;
    @Resource
    RedisTemplate<String, KssUser> redisTemplateUser;
    @Resource
    MessageMqSendUser messageMqSendUser;
    @Transactional
    @PostMapping("/passport/login")
    public KssUserBo loginByMess(@RequestBody KssUserVo kssUser){
        System.out.println(kssUser);
        // 1: 接受用户提交用户手机和短信
        String inputPhone = kssUser.getPhone();
        String inputSmsCode = kssUser.getSmscode();
        // 2: 获取redis缓存中的存储短信
        String cacheSmsCode = redisOperator.get(PUG_XQ_LOGIN_SMS_CODE + inputPhone);
        if(cacheSmsCode==null){
            throw new KsdBusinessException(602,"验证码已经失效");
        }
//        Vsserts.isEmptyEx(cacheSmsCode, "短信已经失效");
        // 3: 对比短信码是否正确
        if (!cacheSmsCode.equalsIgnoreCase(inputSmsCode)) {
            throw new KsdBusinessException(602, "你输入短信证码有误!");
        }
        //删除验证码
        redisTemplateUser.delete(PUG_XQ_LOGIN_SMS_CODE + inputPhone);
        // 4：开始进行业务的处理
        KssUser dbUser = userService.getByPhone(DesUtils.encrypt(inputPhone));
        // 如果dbUser，说明没有注册
        if (Vsserts.isNull(dbUser)) {
            // 开始注册
            dbUser = new KssUser();

            dbUser.setPhone(DesUtils.encrypt(inputPhone));
            dbUser.setIdcode(idWorkService.nextShort());
            dbUser.setNickname("小伴");
            dbUser.setPassword("");
            dbUser.setAvatar("http://121.43.183.166:9000/lqx/50a52204-a5c0-4074-9330-6786221334e0.jpg");
            dbUser.setSex(2);
            dbUser.setCountry("中国");
            dbUser.setProvince("");
            dbUser.setCity("");
            dbUser.setDistrict("");
            dbUser.setDescription("Ta什么都没有留下...");
            dbUser.setBgImg("https://scpic.chinaz.net/files/pic/pic9/202007/apic26488.jpg");
            dbUser.setStatus(1);
            //将用户注册的id（其实是phone）保存在布隆过滤器中
            UserServerApplication.filter_id.put(DesUtils.encrypt(kssUser.getPhone()));
            UserServerApplication.filter_phone.put(kssUser.getPhone());
            //异步保存注册信息(mongodb)
            MessageDto messageDto=new MessageDto();
            messageDto.setAvatar("http://121.43.183.166:9000/lqx/50a52204-a5c0-4074-9330-6786221334e0.jpg");
            messageDto.setIcon("");
            messageDto.setMsgcontent("恭喜您，注册成功！");
            messageDto.setNickname("小伴");
            messageDto.setMsgtype(1);
            messageDto.setTitle("注册通知");
            messageServiceMq.pushMessageSave(messageDto);
            //向mysql保存用户信息
            userService.saveOrUpdate(dbUser);
        }
        //将用户号码放进布隆过滤器中
        UserServerApplication.filter_phone.put(kssUser.getPhone());
        UserServerApplication.filter_id.put(DesUtils.encrypt(kssUser.getPhone()));
        // 5: 存在就返回
        KssUserBo kssUserBo = new KssUserBo();
        BeanUtils.copyProperties(dbUser, kssUserBo);
        // 6: 生成一个uuid代表token
        String uuid = UUID.randomUUID().toString();
        //向redis插入一个token
        stringStringRedisTemplate.opsForValue().set(PUG_XQ_LOGIN_USER_TOKEN+dbUser.getId(),uuid);
        //向redis加入用户的信息，方便以后的使用(无需查询MySQL)
        redisTemplateUser.opsForValue().set(PUG_XQ_LOGIN_USER_INFO+dbUser.getId(),dbUser);

        KssUser kssUser1 = UserThreadLocal.get();
        kssUserBo.setToken(uuid);
        return kssUserBo;
    }

    //账号密码登录
//    @EnableNoToken(value = true)
    @Transactional
    @PostMapping("/passport/loginpwd")
    public KssUserBo loginByPwd(@RequestBody LoginByPwdVo loginByPwdVo){
        if(loginByPwdVo.getPhone()==null){
            throw  new KsdValidationException(ResultEnum.EMPTY_ERROR);
        }
        boolean b = UserServerApplication.filter_id.mightContain(loginByPwdVo.getPhone());
        //对登录模块进行了布隆过滤处理
        if(b==false){
            throw new KsdValidationException(ResultEnum.PLEASE_REGISTER);
        }
        String phone = DesUtils.decrypt(loginByPwdVo.getPhone());
//        String phone = loginByPwdVo.getPhone();
        String password = loginByPwdVo.getPassword();
        KssUser kssUser = userService.selectByPhone(phone);
        /**
         * 目前先不判断
         */
//        if(kssUser==null){
//            throw new KsdBusinessException(600,"账号密码错误");
//        }
//        String decrypt = kssUser.getPassword();
//        if(1==2){  //这个几把加密解密有问题，艹艹艹
//            throw new KsdBusinessException(600,"账号密码错误");
//        }
        KssUserBo kssUserBo = new KssUserBo();
        BeanUtils.copyProperties(kssUser, kssUserBo);
        //token
        String token=UUID.randomUUID().toString();
        stringStringRedisTemplate.opsForValue().set(PUG_XQ_LOGIN_USER_TOKEN+kssUser.getId(),token);
        redisTemplateUser.opsForValue().set(PUG_XQ_LOGIN_USER_INFO+kssUser.getId(),kssUser);
        kssUserBo.setToken(token);
        //通过mq保存用户信息
        UserDto userDto=new UserDto();
        userDto.setTitle("登录");userDto.setUserid(kssUser.getId()+"");userDto.setNickname(kssUser.getNickname());userDto.setMsgtype(1);userDto.setMsgcontent("欢迎登录！");
        messageMqSendUser.pushMessageSave(userDto);
        return kssUserBo;
    }
//    @EnableNoToken(true)
//    @PostMapping("/passport/wxlogin/code")
//    public KssUserBo loginByWeiXin(@RequestBody WeiXinData weiXinData){
//        userService.getOpenId(weiXinData);
//        return null;
//    }

    //退出登录
//    @EnableNoToken(value = true)
    @SaveLog(value = true)
    @PostMapping("/passport/logout")
    public boolean logout(@RequestBody LogoutVo logoutVo){
        log.info("{}:退出登录",logoutVo);
        try {
            String token=logoutVo.getToken();
            String userId=logoutVo.getUserId();
            //删除token
            redisTemplateUser.delete(PUG_XQ_LOGIN_USER_TOKEN+userId);
            //删除redis中的用户信息
            redisTemplateUser.delete(PUG_XQ_LOGIN_USER_INFO+userId);

        }catch (Exception e){
            throw new KsdBusinessException(601,"退出失败");
        }
        log.info("{}:退出登录成功",logoutVo);
        return true;
    }
}
